package com.je.dd.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.je.cache.service.config.JepfCacheManager;
import com.je.cache.service.dic.DicInfoCacheManager;
import com.je.core.constants.ConstantVars;
import com.je.core.constants.dd.DDSQLListType;
import com.je.core.constants.dd.DDType;
import com.je.core.constants.tree.NodeType;
import com.je.core.constants.tree.TreeNodeType;
import com.je.core.dao.PCDaoTemplateImpl;
import com.je.core.entity.ExtendTreeBaseEntity;
import com.je.core.entity.TreeBaseEntity;
import com.je.core.entity.extjs.JSONTreeNode;
import com.je.core.exception.PlatformException;
import com.je.core.exception.PlatformExceptionEnum;
import com.je.core.mapper.query.Condition;
import com.je.core.mapper.query.ConditionEnum;
import com.je.core.mapper.query.Query;
import com.je.core.service.MetaService;
import com.je.core.service.QueryBuilder;
import com.je.core.util.*;
import com.je.core.util.bean.BeanUtils;
import com.je.core.util.bean.DynaBean;
import com.je.dd.vo.DicInfoVo;
import com.je.dd.vo.DictionaryItemVo;
import com.je.ibatis.extension.conditions.ConditionsWrapper;
import com.je.rbac.model.EndUser;
import com.je.rbac.service.AdminPermManager;
import org.apache.commons.lang.StringUtils;
import org.bouncycastle.util.Strings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.persistence.Table;
import java.sql.Clob;
import java.util.*;

/**
 * 树形字典相关接口
 *
 * @author wangmm@ketr.com.cn
 * @date 2020/1/13
 */
@Service
public class TreeServiceImpl implements TreeService {

    @Autowired
    public AdminPermManager adminPermManager;
    private Logger logger = LoggerFactory.getLogger(getClass());
    /**
     * 基础数据操作封装
     */
    @Autowired
    private MetaService metaService;

    /**
     * 读取异步树
     *
     * @param obj      字典查询条件
     * @param en       国际化
     * @param onlyItem 只包含子项
     * @return java.util.List<com.je.core.entity.extjs.JSONTreeNode>
     */
    @Override
    public List<JSONTreeNode> loadAsynTree(JSONObject obj, boolean en, boolean onlyItem) {
        List<JSONTreeNode> array = new ArrayList<>();
        //根节点ID,默认为ROOT
        String rootId = obj.getString("rootId");
        if (StringUtil.isEmpty(rootId)) {
            rootId = ConstantVars.TREE_ROOT;
        }
        //字典编码
        String ddCode = obj.getString("ddCode");
        //字典名称，非必需字段
        String ddName = obj.getString("ddName");
        //字典标识，非必需字段 创建根节点对象ID使用,一次加载多个字典时使用
        String nodeInfo = obj.getString("nodeInfo");
        //默认为1  是否从根节点查找数据
        String isRoot = obj.containsKey("isRoot") ? obj.getString("isRoot") : "1";

        //构建根节点
        JSONTreeNode emptyRoot = new JSONTreeNode();
        emptyRoot.setText(ddName);
        emptyRoot.setParent("ROOT");
        emptyRoot.setId("ROOT_" + nodeInfo);
        emptyRoot.setIconCls("jeicon jeicon-tree-query");
        emptyRoot.setNodeInfo(nodeInfo);

        //查找字典主表记录

        DynaBean dictionary = DicInfoCacheManager.getCacheValue(ddCode);
        if (dictionary == null) {
            dictionary = metaService.selectOne("JE_CORE_DICTIONARY", ConditionsWrapper.builder().eq("DICTIONARY_DDCODE", ddCode));
        }
        if (dictionary == null) {
            array.add(emptyRoot);
            throw new PlatformException("未找到数据字典：" + ddCode + "!", PlatformExceptionEnum.JE_CORE_DIC_UNKOWN_ERROR, new Object[]{ddCode});
        }

        //字典类型，本方法支持[外部树形字典，列表字典，树形字典]
        String ddType = dictionary.getStr("DICTIONARY_DDTYPE");
        //字典对应表名，普通列表与普通树形字典此值为空
        String tableName = dictionary.getStr("DICTIONARY_CLASSNAME");


        if (!DDType.DYNA_TREE.equalsIgnoreCase(ddType) && !DDType.LIST.equalsIgnoreCase(ddType) && !DDType.TREE.equalsIgnoreCase(ddType)) {
            array.add(emptyRoot);
            logger.error("传入的字典类型出错，字典编码:【" + ddCode + "】!");
            return array;
        }

        if (DDType.LIST.equalsIgnoreCase(ddType) || DDType.TREE.equalsIgnoreCase(ddType)) {
            if ("1".equals(obj.getString("zwfFlag"))) {
                // 自维护字典
                tableName = "JE_JTGS_DICTIONARYITEM";
            } else {
                // 普通字典
                tableName = "JE_CORE_DICTIONARYITEM";
            }
        }

        //前端sql条件转换
        Query query;
        if (StringUtils.isNotBlank(obj.getString("j_query"))) {
            query = Query.build(obj.getString("j_query"));
        } else {
            query = new Query();
        }

        //过滤平台核心
        String[] tables = JepfCacheManager.getCacheValue("SY_JECORETABLES").split(",");
        if (ArrayUtils.contains(tables, tableName)) {
            //SY_JESYS='1'
            Condition condition = query.findCondition("SY_JESYS", "1");
            if ("1".equals(WebUtils.getSysVar("SY_JECORE"))) {

                //SY_JECORE!='1'
                Condition sy_jecore = new Condition("SY_JECORE", ConditionEnum.NE.getType(), "1");
                //SY_JECORE IS NULL
                Condition sy_jecore_null = new Condition("SY_JECORE", ConditionEnum.IS_NULL.getType(), "", "OR");

                if (condition != null) {
//                    querySql = querySql.replace("SY_JESYS='1'", "(SY_JESYS='1' OR (SY_JECORE!='1' OR SY_JECORE IS NULL))");
                    condition.setCode("");
                    //修改条件为 and() 或 or()
                    condition.setType("or".equalsIgnoreCase(condition.getCn()) ? ConditionEnum.OR.getType() : ConditionEnum.AND.getType());
                    //SY_JESYS='1'
                    Condition sy_jesys = new Condition("SY_JESYS", ConditionEnum.EQ.getType(), "1");
                    //OR (SY_JECORE!='1' OR SY_JECORE IS NULL))
                    Condition conditionOr = new Condition("", ConditionEnum.OR.getType(), Lists.newArrayList(sy_jecore, sy_jecore_null));
                    //SY_JESYS='1' OR (SY_JECORE!='1' OR SY_JECORE IS NULL)
                    condition.setValue(Lists.newArrayList(sy_jesys, conditionOr));
                } else {
//                    querySql += " AND (SY_JECORE!='1' OR SY_JECORE IS NULL)";
                    Condition conditionAnd = new Condition();
                    conditionAnd.setType(ConditionEnum.AND.getType());
                    conditionAnd.setValue(Lists.newArrayList(sy_jecore, sy_jecore_null));
                    query.getCustom().add(conditionAnd);
                }
            } else if (condition != null) {
                // SY_JECORE != 1 时去除条件 SY_JESYS='1'
                // querySql = querySql.replace("SY_JESYS='1'", "1=1");
                query.getCustom().remove(condition);
            }
        }

        // 租户ID
        String adminPermSql = "";
        String[] rbacTables = new String[]{"JE_CORE_DEPARTMENT", "JE_CORE_SENTRY", "JE_CORE_ROLE", "JE_CORE_VDEPTUSER", "JE_CORE_VROLEUSER", "JE_CORE_VSENTRYUSER"};
        if (ArrayUtils.contains(rbacTables, tableName)) {
            if (WebUtils.isSaas()) {

                //租户条件
                Condition conditionZh = new Condition("ZHID", ConditionEnum.EQ.getType(), SecurityUserHolder.getCurrentUser().getZhId());
                //查找条件
                Condition findZh = query.findCondition("ZHID");
                Condition findRole = query.findCondition("ROLERANK", "SYS");
                if (findZh == null && (!"JE_CORE_ROLE".equals(tableName) || findRole == null)) {
                    query.getCustom().add(conditionZh);
                }
            } else {
                if ("JE_CORE_ROLE".equals(tableName)) {
                    if (query.findCondition("ROLERANK", "SYS") == null) {
                        query.getCustom().add(new Condition("ROLERANK", ConditionEnum.EQ.getType(), "SYS"));
                    }
                }
                if (obj.containsKey("params")) {
                    JSONObject varObj = obj.getJSONObject("params");
                    if (varObj.containsKey("ADMINPERM") && "1".equals(varObj.getString("ADMINPERM"))) {
                        adminPermSql = adminPermManager.getQuerySql(tableName);
                    }
                }
            }
        }

        //条件构建器 //添加 adminPermSql
        ConditionsWrapper wrapper = query.buildWrapper();
        //获取Admin权限sql
        String queryTableCode = obj.getString("queryTableCode");
        if (StringUtils.isNotBlank(queryTableCode)) {
            adminPermSql = adminPermManager.getQuerySql(queryTableCode);
            if (StringUtils.isNotBlank(adminPermSql)) {
                final String sql = adminPermSql;
                wrapper.and(i -> i.apply(QueryBuilder.trimSql(sql)));
            }
        }

        //自维护字典与普通字典
        if ("JE_JTGS_DICTIONARYITEM".equals(tableName)) {
            // 自维护字典
            wrapper.eq("DICTIONARYITEM_DICTIONARY_ID", dictionary.getStr("JE_CORE_DICTIONARY_ID"));
            //查找根节点
            if ("1".equals(isRoot)) {
                //拼接租户sql
                wrapper.eq("SY_ZHID", SecurityUserHolder.getCurrentUser().getZhId());
                //构建查询根节点
                DynaBean beanRoot = metaService.selectOne(tableName, wrapper.clone().eq("SY_NODETYPE", "ROOT"),
                        "JE_JTGS_DICTIONARYITEM_ID,SY_NODETYPE");
                rootId = beanRoot.getStr("JE_JTGS_DICTIONARYITEM_ID");
            }
            wrapper.eq("SY_FLAG", "1");
        } else if ("JE_CORE_DICTIONARYITEM".equals(tableName)) {
            // 普通字典
            wrapper.eq("DICTIONARYITEM_DICTIONARY_ID", dictionary.getStr("JE_CORE_DICTIONARY_ID"));
            //查找根节点
            if ("1".equals(isRoot)) {
                if (ConstantVars.TREE_ROOT.equals(rootId)) {
                    rootId = dictionary.getStr("DICTIONARY_ITEMROOT_ID");
                }
            }
            wrapper.eq("SY_FLAG", "1");
        }

        //获取树形信息
        DynaBean table = BeanUtils.getInstance().getResourceTable(tableName);
        if (table == null) {
            array.add(emptyRoot);
            return array;
        }
        //构建dyanBean的树形模版
        JSONTreeNode template = BeanUtils.getInstance().buildJSONTreeNodeTemplate((List<DynaBean>) table.get(BeanUtils.KEY_TABLE_COLUMNS));
        //普通字典国际化处理
        if ("JE_CORE_DICTIONARYITEM".equals(tableName) && en) {
            template.setText("DICTIONARYITEM_ITEMNAME_EN");
            template.setEnField("DICTIONARYITEM_ITEMNAME");
        }

        //字典配置sql条件
        String ddWhereSql = dictionary.getStr("DICTIONARY_WHERESQL", "");
        String ddOrderSql = dictionary.getStr("DICTIONARY_ORDERSQL", "");

        // 添加字典配置sql
        if (StringUtil.isNotEmpty(ddWhereSql)) {
            //formatSqlParameter 替换Sql中的系统变量 非预处理赋值
            wrapper.apply(QueryBuilder.formatSqlParameter(ddWhereSql));
        }

        //排序条件
        String orderSql = query.buildOrder();
        if (StringUtils.isNotBlank(orderSql)) {
            orderSql = " ORDER BY " + orderSql;
        } else if (StringUtils.isNotBlank(ddOrderSql)) {
            orderSql = ddOrderSql;
        }
        wrapper.getParameter().put("orderSql", orderSql);

        //查询数据
        List<JSONTreeNode> jsonTreeNodeList = loadAsyncTreeNodeList(rootId, tableName, template, wrapper, "1".equals(isRoot), false);

        //添加根节点数据
        if ("1".equals(isRoot)) {
            JSONTreeNode root = new JSONTreeNode();
            root.setId(rootId);
            jsonTreeNodeList.add(root);
        }
        for (JSONTreeNode node : jsonTreeNodeList) {
            if (node.getId().equals(rootId) && "1".equals(isRoot)) {
                node.setText(ddName);
                node.setIconCls("jeicon jeicon-tree-query");
                node.setParent("ROOT");
                node.setDisabled("1");
                if (StringUtil.isNotEmpty(nodeInfo)) {
                    node.setNodeInfo(nodeInfo);
                    node.setId(node.getId() + "_" + nodeInfo);
                }
            } else {
                if (StringUtil.isNotEmpty(nodeInfo)) {
                    node.setNodeInfo(nodeInfo);
                    node.setId(node.getId() + "_" + nodeInfo);
                    node.setParent(node.getParent() + "_" + nodeInfo);
                }
            }
            if (tableName.equals("JE_CORE_DICTIONARYITEM")) {
                node.setBean(new HashMap<String, Object>());
            }
        }
        if ("1".equals(isRoot)) {
            if (StringUtil.isNotEmpty(nodeInfo)) {
                rootId = rootId + "_" + nodeInfo;
            }
            JSONTreeNode rootNode = buildJSONNewTree(jsonTreeNodeList, rootId);

            if (onlyItem) {
                array.addAll(rootNode.getChildren());
            } else {
                array.add(rootNode);
            }
        } else {
            array.addAll(jsonTreeNodeList);
        }
        return array;
    }

    /**
     * 异步树时查找接口
     *
     * @param obj       字典查询条件
     * @param queryType 查找类型
     * @param value     查找值
     * @param en        国际化
     * @param onlyItem  只包含子项
     * @return java.util.List<com.je.core.entity.extjs.JSONTreeNode>
     */
    @Override
    public List<JSONTreeNode> findAsyncNodes(JSONObject obj, String queryType, String value, boolean en, boolean onlyItem) {
        List<JSONTreeNode> array = new ArrayList<>();
        //根节点ID,默认为ROOT
        String rootId = obj.getString("rootId");
        if (StringUtil.isEmpty(rootId)) {
            rootId = ConstantVars.TREE_ROOT;
        }
        //字典编码
        String ddCode = obj.getString("ddCode");
        //字典名称，非必需字段
        String ddName = obj.getString("ddName");
        //字典标识，非必需字段 创建根节点对象ID使用,一次加载多个字典时使用
        String nodeInfo = obj.getString("nodeInfo");
        //默认为1  是否从根节点查找数据
        String isRoot = obj.containsKey("isRoot") ? obj.getString("isRoot") : "1";

        //构建根节点
        JSONTreeNode emptyRoot = new JSONTreeNode();
        emptyRoot.setText(ddName);
        emptyRoot.setParent("ROOT");
        emptyRoot.setId("ROOT_" + nodeInfo);
        emptyRoot.setIconCls("jeicon jeicon-tree-query");
        emptyRoot.setNodeInfo(nodeInfo);

        //查找字典主表记录

        DynaBean dictionary = DicInfoCacheManager.getCacheValue(ddCode);
        if (dictionary == null) {
            dictionary = metaService.selectOne("JE_CORE_DICTIONARY", ConditionsWrapper.builder().eq("DICTIONARY_DDCODE", ddCode));
        }
        if (dictionary == null) {
            array.add(emptyRoot);
            throw new PlatformException("未找到数据字典：" + ddCode + "!", PlatformExceptionEnum.JE_CORE_DIC_UNKOWN_ERROR, new Object[]{ddCode});
        }

        //字典类型，本方法支持[外部树形字典，列表字典，树形字典]
        String ddType = dictionary.getStr("DICTIONARY_DDTYPE");
        //字典对应表名，普通列表与普通树形字典此值为空
        String tableName = dictionary.getStr("DICTIONARY_CLASSNAME");


        if (!DDType.DYNA_TREE.equalsIgnoreCase(ddType) && !DDType.LIST.equalsIgnoreCase(ddType) && !DDType.TREE.equalsIgnoreCase(ddType)) {
            array.add(emptyRoot);
            logger.error("传入的字典类型出错，字典编码:【" + ddCode + "】!");
            return array;
        }

        if (DDType.LIST.equalsIgnoreCase(ddType) || DDType.TREE.equalsIgnoreCase(ddType)) {
            if ("1".equals(obj.getString("zwfFlag"))) {
                // 自维护字典
                tableName = "JE_JTGS_DICTIONARYITEM";
            } else {
                // 普通字典
                tableName = "JE_CORE_DICTIONARYITEM";
            }
        }

        //前端sql条件转换
        Query query;
        if (StringUtils.isNotBlank(obj.getString("j_query"))) {
            query = Query.build(obj.getString("j_query"));
        } else {
            query = new Query();
        }

        //过滤平台核心
        String[] tables = JepfCacheManager.getCacheValue("SY_JECORETABLES").split(",");
        if (ArrayUtils.contains(tables, tableName)) {
            //SY_JESYS='1'
            Condition condition = query.findCondition("SY_JESYS", "1");
            if ("1".equals(WebUtils.getSysVar("SY_JECORE"))) {

                //SY_JECORE!='1'
                Condition sy_jecore = new Condition("SY_JECORE", ConditionEnum.NE.getType(), "1");
                //SY_JECORE IS NULL
                Condition sy_jecore_null = new Condition("SY_JECORE", ConditionEnum.IS_NULL.getType(), "", "OR");

                if (condition != null) {
//                    querySql = querySql.replace("SY_JESYS='1'", "(SY_JESYS='1' OR (SY_JECORE!='1' OR SY_JECORE IS NULL))");
                    condition.setCode("");
                    //修改条件为 and() 或 or()
                    condition.setType("or".equalsIgnoreCase(condition.getCn()) ? ConditionEnum.OR.getType() : ConditionEnum.AND.getType());
                    //SY_JESYS='1'
                    Condition sy_jesys = new Condition("SY_JESYS", ConditionEnum.EQ.getType(), "1");
                    //OR (SY_JECORE!='1' OR SY_JECORE IS NULL))
                    Condition conditionOr = new Condition("", ConditionEnum.OR.getType(), Lists.newArrayList(sy_jecore, sy_jecore_null));
                    //SY_JESYS='1' OR (SY_JECORE!='1' OR SY_JECORE IS NULL)
                    condition.setValue(Lists.newArrayList(sy_jesys, conditionOr));
                } else {
//                    querySql += " AND (SY_JECORE!='1' OR SY_JECORE IS NULL)";
                    Condition conditionAnd = new Condition();
                    conditionAnd.setType(ConditionEnum.AND.getType());
                    conditionAnd.setValue(Lists.newArrayList(sy_jecore, sy_jecore_null));
                    query.getCustom().add(conditionAnd);
                }
            } else if (condition != null) {
                // SY_JECORE != 1 时去除条件 SY_JESYS='1'
                // querySql = querySql.replace("SY_JESYS='1'", "1=1");
                query.getCustom().remove(condition);
            }
        }

        // 租户ID
        String adminPermSql = "";
        String[] rbacTables = new String[]{"JE_CORE_DEPARTMENT", "JE_CORE_SENTRY", "JE_CORE_ROLE", "JE_CORE_VDEPTUSER", "JE_CORE_VROLEUSER", "JE_CORE_VSENTRYUSER"};
        if (ArrayUtils.contains(rbacTables, tableName)) {
            if (WebUtils.isSaas()) {

                //租户条件
                Condition conditionZh = new Condition("ZHID", ConditionEnum.EQ.getType(), SecurityUserHolder.getCurrentUser().getZhId());
                //查找条件
                Condition findZh = query.findCondition("ZHID");
                Condition findRole = query.findCondition("ROLERANK", "SYS");
                if (findZh == null && (!"JE_CORE_ROLE".equals(tableName) || findRole == null)) {
                    query.getCustom().add(conditionZh);
                }
            } else {
                if ("JE_CORE_ROLE".equals(tableName)) {
                    if (query.findCondition("ROLERANK", "SYS") == null) {
                        query.getCustom().add(new Condition("ROLERANK", ConditionEnum.EQ.getType(), "SYS"));
                    }
                }
                if (obj.containsKey("params")) {
                    JSONObject varObj = obj.getJSONObject("params");
                    if (varObj.containsKey("ADMINPERM") && "1".equals(varObj.getString("ADMINPERM"))) {
                        adminPermSql = adminPermManager.getQuerySql(tableName);
                    }
                }
            }
        }
        //获取树形信息
        DynaBean table = BeanUtils.getInstance().getResourceTable(tableName);
        if (table == null) {
            array.add(emptyRoot);
            return array;
        }
        //构建dyanBean的树形模版
        JSONTreeNode template = BeanUtils.getInstance().buildJSONTreeNodeTemplate((List<DynaBean>) table.get(BeanUtils.KEY_TABLE_COLUMNS));
        //普通字典国际化处理
        if ("JE_CORE_DICTIONARYITEM".equals(tableName) && en) {
            template.setText("DICTIONARYITEM_ITEMNAME_EN");
            template.setEnField("DICTIONARYITEM_ITEMNAME");
        }

        if ("id".equals(queryType)) {
            query.addCustom(template.getId(), ConditionEnum.IN, value.split(","));
        } else if ("code".equals(queryType)) {
            query.addCustom(template.getCode(), ConditionEnum.IN, value.split(","));
        } else if ("text".equals(queryType)) {
            query.addCustom(template.getText(), ConditionEnum.IN, value.split(","));
        } else if ("liketext".equals(queryType)) {
            query.addCustom(template.getText(), ConditionEnum.LIKE, value);
        } else if ("rootId".equals(queryType)) {
            // 查询指定节点下所有的叶子节点
            rootId = value;
            query.addCustom(template.getNodeType(), ConditionEnum.EQ, "LEAF");
            query.addCustom(template.getNodePath(), ConditionEnum.LIKE, value);
        }

        //条件构建器 //添加 adminPermSql
        ConditionsWrapper wrapper = query.buildWrapper();
        //获取Admin权限sql
        String queryTableCode = obj.getString("queryTableCode");
        if (StringUtils.isNotBlank(queryTableCode)) {
            adminPermSql = adminPermManager.getQuerySql(queryTableCode);
            if (StringUtils.isNotBlank(adminPermSql)) {
                final String sql = adminPermSql;
                wrapper.and(i -> i.apply(QueryBuilder.trimSql(sql)));
            }
        }

        //自维护字典与普通字典
        if ("JE_JTGS_DICTIONARYITEM".equals(tableName)) {
            // 自维护字典
            wrapper.eq("DICTIONARYITEM_DICTIONARY_ID", dictionary.getStr("JE_CORE_DICTIONARY_ID"));
            //查找根节点
            if ("1".equals(isRoot)) {
                //拼接租户sql
                wrapper.eq("SY_ZHID", SecurityUserHolder.getCurrentUser().getZhId());
                //构建查询根节点
                DynaBean beanRoot = metaService.selectOne(tableName, wrapper.clone().eq("SY_NODETYPE", "ROOT"),
                        "JE_JTGS_DICTIONARYITEM_ID,SY_NODETYPE");
                rootId = beanRoot.getStr("JE_JTGS_DICTIONARYITEM_ID");
            }
            wrapper.eq("SY_FLAG", "1");
        } else if ("JE_CORE_DICTIONARYITEM".equals(tableName)) {
            // 普通字典
            wrapper.eq("DICTIONARYITEM_DICTIONARY_ID", dictionary.getStr("JE_CORE_DICTIONARY_ID"));
            //查找根节点
            if ("1".equals(isRoot)) {
                if (ConstantVars.TREE_ROOT.equals(rootId)) {
                    rootId = dictionary.getStr("DICTIONARY_ITEMROOT_ID");
                }
            }
            wrapper.eq("SY_FLAG", "1");
        }
        //字典配置sql条件
        String ddWhereSql = dictionary.getStr("DICTIONARY_WHERESQL", "");
        String ddOrderSql = dictionary.getStr("DICTIONARY_ORDERSQL", "");

        // 添加字典配置sql
        if (StringUtil.isNotEmpty(ddWhereSql)) {
            //formatSqlParameter 替换Sql中的系统变量 非预处理赋值
            wrapper.apply(QueryBuilder.formatSqlParameter(ddWhereSql));
        }

        //排序条件
        String orderSql = query.buildOrder();
        if (StringUtils.isNotBlank(orderSql)) {
            orderSql = " ORDER BY " + orderSql;
        } else if (StringUtils.isNotBlank(ddOrderSql)) {
            orderSql = ddOrderSql;
        }
        wrapper.getParameter().put("orderSql", orderSql);

        //查询数据
        return loadTreeNodeList(rootId, tableName, template, wrapper, null, null);
    }

    /**
     * 读取同步树
     *
     * @param obj      字典查询条件
     * @param en       国际化
     * @param onlyItem 只包含子项
     * @return java.util.List<com.je.core.entity.extjs.JSONTreeNode>
     */
    @Override
    public List<JSONTreeNode> loadSyncTree(JSONObject obj, boolean en, boolean onlyItem) {

        List<JSONTreeNode> array = new ArrayList<>();

        //根节点ID,默认为ROOT
        String rootId = obj.getString("rootId");
        if (StringUtil.isEmpty(rootId)) {
            rootId = ConstantVars.TREE_ROOT;
        }
        //字典编码
        String ddCode = obj.getString("ddCode");
        //字典名称，非必需字段
        String ddName = obj.getString("ddName");
        //字典标识，非必需字段 创建根节点对象ID使用,一次加载多个字典时使用
        String nodeInfo = obj.getString("nodeInfo");
        //默认为1  是否从根节点查找数据
        String isRoot = obj.containsKey("isRoot") ? obj.getString("isRoot") : "1";

        String moreRoot = "0";
        //是否缓存
        String dataCache = "0";
        if (obj.containsKey("params")) {
            JSONObject varObj = obj.getJSONObject("params");
            if (varObj.containsKey("dataCache")) {
                dataCache = varObj.getString("dataCache");
            }
            if (varObj.containsKey("moreRoot")) {
                moreRoot = varObj.getString("moreRoot");
            }
        }

        //当前用户
        EndUser currentUser = SecurityUserHolder.getCurrentUser();

        //构建根节点
        JSONTreeNode emptyRoot = new JSONTreeNode();
        emptyRoot.setText(ddName);
        emptyRoot.setParent("ROOT");
        emptyRoot.setId("ROOT_" + nodeInfo);
        emptyRoot.setIconCls("jeicon jeicon-tree-query");
        emptyRoot.setNodeInfo(nodeInfo);

        //查找字典主表记录
        DynaBean dictionary = DicInfoCacheManager.getCacheValue(ddCode);
        if (dictionary == null) {
            dictionary = metaService.selectOne("JE_CORE_DICTIONARY", ConditionsWrapper.builder().eq("DICTIONARY_DDCODE", ddCode));

            if (dictionary == null) {
                throw new PlatformException("未找到数据字典：" + ddCode + "!", PlatformExceptionEnum.JE_CORE_DIC_UNKOWN_ERROR, new Object[]{ddCode});
            }
        }

        //字典类型
        String ddType = dictionary.getStr("DICTIONARY_DDTYPE");
        //字典对应表名或类名
        String tableName = dictionary.getStr("DICTIONARY_CLASSNAME");

        //字典配置sql
        String ddWhereSql = dictionary.getStr("DICTIONARY_WHERESQL", "");
        String ddOrderSql = dictionary.getStr("DICTIONARY_ORDERSQL", "");

        //前端sql条件转换
        Query query;
        if (StringUtils.isNotBlank(obj.getString("j_query"))) {
            query = Query.build(obj.getString("j_query"));
        } else {
            query = new Query();
        }

        List<Condition> customQuery = (List<Condition>) obj.get("customQuery");
        query.addCustoms(JSONArray.toJSONString(customQuery));


        //排序条件
        String orderSql = "";
        if (!query.getOrder().isEmpty()) {
            orderSql = " ORDER BY " + query.buildOrder();
        } else if (StringUtils.isNotBlank(ddOrderSql)) {
            orderSql = ddOrderSql;
        }

        if (DDType.MODEL_TREE.equalsIgnoreCase(ddType)) {
            try {

                //实体树形字典 已废弃
                Object entity = Class.forName(tableName).newInstance();
                if (entity != null && (entity instanceof TreeBaseEntity || entity instanceof ExtendTreeBaseEntity)) {
                    JSONTreeNode template = EntityUtils.getInstance().buildJSONTreeNode((TreeBaseEntity) entity);
                    String treeEntityTableName;
                    Table annotation = entity.getClass().getAnnotation(Table.class);
                    if (annotation != null) {
                        treeEntityTableName = annotation.name();
                    } else {
                        treeEntityTableName = entity.getClass().getSimpleName();
                    }
                    //创建查询条件
                    ConditionsWrapper wrapper = query.buildWrapper();
                    wrapper.getParameter().put("orderSql", orderSql);
                    //加载数据
                    List<JSONTreeNode> jsonTreeNodeList = loadTreeNodeList(rootId, treeEntityTableName, template, wrapper);
                    for (JSONTreeNode node : jsonTreeNodeList) {
                        if (node.getId().equals(rootId)) {
                            node.setText(ddName);
                            node.setIconCls("jeicon jeicon-tree-query");
                            node.setParent("ROOT");
                            node.setDisabled("1");
                            if (StringUtil.isNotEmpty(nodeInfo)) {
                                node.setNodeInfo(nodeInfo);
                                node.setId(node.getId() + "_" + nodeInfo);
                            }
                        } else if (StringUtil.isNotEmpty(nodeInfo)) {
                            node.setNodeInfo(nodeInfo);
                            node.setId(node.getId() + "_" + nodeInfo);
                            node.setParent(node.getParent() + "_" + nodeInfo);
                        }
                    }
                    if (StringUtil.isNotEmpty(nodeInfo)) {
                        rootId = rootId + "_" + nodeInfo;
                    }
                    //构建树形节点
                    JSONTreeNode rootNode = buildJSONNewTree(jsonTreeNodeList, rootId);
                    rootNode.setText(ddName);
                    rootNode.setParent("ROOT");
                    rootNode.setIconCls("jeicon jeicon-tree-query");
                    if (onlyItem) {
                        array.addAll(rootNode.getChildren());
                    } else {
                        array.add(rootNode);
                    }
                } else {
                    array.add(emptyRoot);
                    logger.error("获取实体信息出错!");
                }
            } catch (Exception e) {
                logger.error("获取实体信息出错!");
                e.printStackTrace();
            }
        } else if (DDType.CUSTOM.equalsIgnoreCase(ddType)) {
            //自定义后端
            // 无 ddWhereSql ddOrderSql
            String beanName = dictionary.getStr("DICTIONARY_CLASS");
            String beanMethod = dictionary.getStr("DICTIONARY_METHOD");
            HashMap<String, String> params = new HashMap<String, String>();
            if (obj.containsKey("params")) {
                JSONObject varObj = obj.getJSONObject("params");
                for (String key : (Set<String>) varObj.keySet()) {
                    params.put(key, varObj.getString(key));
                }
            }
            DicInfoVo dicInfoVo = new DicInfoVo();
            dicInfoVo.setParams(params);
            dicInfoVo.setRootId(rootId);
            dicInfoVo.setDdCode(ddCode);
            dicInfoVo.setFieldName(ddName);
            dicInfoVo.setFieldCode(nodeInfo);
            if (StringUtil.isNotEmpty(nodeInfo)) {
                dicInfoVo.setIdSuffix("_" + nodeInfo);
            }
            //TODO 暂时使用whereSql 后续去除
            if (!query.getOrder().isEmpty()) {
                dicInfoVo.setOrderSql(JSONObject.toJSONString(query.getOrder()));
            }
            if (!query.getCustom().isEmpty()) {
                dicInfoVo.setWhereSql(JSONObject.toJSONString(query.getCustom()));
            }
            dicInfoVo.setConditions(query.getCustom());
//            dicInfoVo.setOrderSql(JSONObject.toJSONString(query.getOrder()));
//            dicInfoVo.setWhereSql(JSONObject.toJSONString(query.getCustom()));

            Object bean = SpringContextHolder.getBean(beanName);
            JSONTreeNode rootNode = (JSONTreeNode) ReflectionUtils.getInstance().invokeMethod(bean, beanMethod, new Object[]{dicInfoVo});
            if (onlyItem) {
                array.addAll(rootNode.getChildren());
            } else {
                array.add(rootNode);
            }
        } else if (DDType.SQL_TREE.equalsIgnoreCase(ddType)) {
            //动态SQL树形字典

            //字典sql语句
            String sql = dictionary.getStr("DICTIONARY_SQL");
            //sql查询结果字段与树形字段配置
            String sqlConfig = dictionary.getStr("DICTIONARY_SQLCONFIG");
            if (StringUtil.isNotEmpty(sql) && StringUtil.isNotEmpty(sqlConfig)) {

                //树形字段配置
                JSONArray config = JSON.parseArray(sqlConfig);
                //参数集合
                JSONObject varObj = null;
                if (obj.containsKey("params")) {
                    varObj = obj.getJSONObject("params");
                }

                //构建查询器
                ConditionsWrapper sqlSelect = ConditionsWrapper.builder();

                //添加字典语句和条件
                sqlSelect.apply(QueryBuilder.formatSqlParameter(sql))
                        .apply(StringUtil.isNotEmpty(ddWhereSql), QueryBuilder.formatSqlParameter(varObj, ddWhereSql));

                //拼接query条件
                query.buildWrapper(sqlSelect);

                //添加字典排序条件
                if (StringUtil.isEmpty(orderSql) && StringUtil.isNotEmpty(ddOrderSql)) {
                    orderSql = ddOrderSql;
                }
                sqlSelect.apply(QueryBuilder.formatSqlParameter(varObj, orderSql));
                //执行查询
                List<Map<String, Object>> list = metaService.selectSql(sqlSelect);

                //构建树形数据
                List<JSONTreeNode> jsonTreeNodeList = new ArrayList<>();
                for (Map<String, Object> map : list) {
                    //初始化树形对象
                    JSONTreeNode node = new JSONTreeNode();
                    //遍历树形字段配置
                    for (int i = 0; i < config.size(); i++) {
                        JSONObject field = config.getJSONObject(i);
                        //树形字段类型
                        String fieldType = field.getString("code");
                        //树形字段对应结果集中字段名
                        String fieldName = field.getString("value");
                        if (StringUtil.isNotEmpty(fieldName)) {
                            //字段值
                            String value = map.get(fieldName) + "";
                            //根据不同fieldType放入对应字段
                            if (TreeNodeType.ID.toString().equals(fieldType)) {
                                node.setId(value);
                            } else if (TreeNodeType.TEXT.toString().equals(fieldType)) {
                                node.setText(value);
                            } else if (TreeNodeType.CODE.toString().equals(fieldType)) {
                                node.setCode(value);
                            } else if (TreeNodeType.PARENT.toString().equals(fieldType)) {
                                node.setParent(value);
                            } else if (TreeNodeType.NODETYPE.toString().equals(fieldType)) {
                                node.setNodeType(value);
                                node.setLeaf(NodeType.LEAF.equals(value));
                            } else if (TreeNodeType.NODEINFO.toString().equals(fieldType)) {
                                node.setNodeInfo(value);
                            } else if (TreeNodeType.NODEINFOTYPE.toString().equals(fieldType)) {
                                node.setNodeInfoType(value);
                            } else if (TreeNodeType.NODEPATH.toString().equals(fieldType)) {
                                node.setNodePath(value);
                            } else if (TreeNodeType.PARENTPATH.toString().equals(fieldType)) {
                                node.setParentPath(value);
                            } else if (TreeNodeType.DISABLED.toString().equals(fieldType)) {
                                node.setDisabled(value);
                            } else if (TreeNodeType.ORDERINDEX.toString().equals(fieldType)) {
                                if (StringUtil.isNotEmpty(value)) {
                                    node.setOrderIndex(value);
                                } else {
                                    node.setOrderIndex("0");
                                }
                            } else if (TreeNodeType.ICON.toString().equals(fieldType)) {
                                node.setIcon(value);
                            } else if (TreeNodeType.ICONCLS.toString().equals(fieldType)) {
                                node.setIconCls(value);
                            } else if (TreeNodeType.HREF.toString().equals(fieldType)) {
                                node.setHref(value);
                            } else if (TreeNodeType.HREFTARGET.toString().equals(fieldType)) {
                                node.setHrefTarget(value);
                            } else if (TreeNodeType.DESCRIPTION.toString().equals(fieldType)) {
                                node.setDescription(value);
                            }
                        }
                    }
                    //加入树形结果集
                    jsonTreeNodeList.add(node);
                }
                //补充树形字段值
                for (JSONTreeNode node : jsonTreeNodeList) {
                    if (node.getNodeType().equals(NodeType.ROOT)) {
                        rootId = node.getId();
                        node.setDisabled("1");
                        if (StringUtil.isNotEmpty(nodeInfo)) {
                            node.setId(node.getId() + "_" + nodeInfo);
                            node.setNodeInfo(nodeInfo);
                        }
                    } else {
                        node.setDisabled("0");
                        if (StringUtil.isNotEmpty(nodeInfo)) {
                            node.setNodeInfo(nodeInfo);
                            node.setId(node.getId() + "_" + nodeInfo);
                            node.setParent(node.getParent() + "_" + nodeInfo);
                        }
                    }
                }
                if (StringUtil.isNotEmpty(nodeInfo)) {
                    rootId = rootId + "_" + nodeInfo;
                }
                JSONTreeNode rootNode = buildJSONNewTree(jsonTreeNodeList, rootId);
                rootNode.setText(ddName);
                rootNode.setParent("ROOT");
                rootNode.setIconCls("jeicon jeicon-tree-query");
                if (onlyItem) {
                    array.addAll(rootNode.getChildren());
                } else {
                    array.add(rootNode);
                }
            } else {
                array.add(emptyRoot);
                logger.error("SQL动态字段信息错误,字典:【" + ddCode + "】参数值:【" + sql + "】,配置：【" + sqlConfig + "】!");
            }

        } else if (DDType.SQL.equalsIgnoreCase(ddType)) {
            //动态SQL列表字典

            //字典sql语句
            String sql = dictionary.getStr("DICTIONARY_SQL");
            if (Strings.toLowerCase(sql).indexOf("where") == -1 && Strings.toLowerCase(sql).indexOf("group") == -1) {
                sql += " WHERE 1=1 ";
            }
            //sql查询结果字段与树形字段配置
            String sqlConfig = dictionary.getStr("DICTIONARY_SQLPZXXLB");
            if (StringUtil.isNotEmpty(sql) && StringUtil.isNotEmpty(sqlConfig)) {

                //树形字段配置
                JSONArray config = JSON.parseArray(sqlConfig);
                //参数集合
                JSONObject varObj = null;
                if (obj.containsKey("params")) {
                    varObj = obj.getJSONObject("params");
                }

                //构建查询器
                ConditionsWrapper sqlSelect = ConditionsWrapper.builder();

                //添加字典语句和条件
                sqlSelect.apply(QueryBuilder.formatSqlParameter(varObj, sql))
                        .apply(StringUtil.isNotEmpty(ddWhereSql), QueryBuilder.formatSqlParameter(varObj, ddWhereSql));

                //拼接query条件
                query.buildWrapper(sqlSelect);

                //添加字典排序条件
                if (StringUtil.isEmpty(orderSql) && StringUtil.isNotEmpty(ddOrderSql)) {
                    orderSql = ddOrderSql;
                }
                sqlSelect.apply(QueryBuilder.formatSqlParameter(varObj, orderSql));
                //执行查询
                List<Map<String, Object>> list = metaService.selectSql(sqlSelect);

                //是否包含多值字段
                boolean isMore = false;
                //字段标准，按照顺序的标准规则，示例： 名称->张,李
                String fieldStandard = "";
                Map<String, String> fieldSplitName = new HashMap<>();

                for (int i = 0; i < config.size(); i++) {
                    JSONObject field = config.getJSONObject(i);
                    //字段类型
                    String fieldType = field.getString("code");
                    //
                    String fieldName = field.getString("value");
                    if (StringUtil.isEmpty(fieldName)) {
                        continue;
                    }
                    //动态列表字典，多值字段类型 isMore = true
                    if (ArrayUtils.contains(new String[]{DDSQLListType.ID_S, DDSQLListType.NAME_S, DDSQLListType.CODE_S, DDSQLListType.ICONCLS_S}, fieldType)) {
                        isMore = true;
                        fieldStandard = fieldType;
                        fieldSplitName.put(fieldType, fieldName);
                    }
                }

                //构建树形数据
                List<JSONTreeNode> jsonTreeNodeList = new ArrayList<>();
                for (Map<String, Object> map : list) {
                    //初始化树形对象
                    JSONTreeNode ddValue = new JSONTreeNode();
                    //字典值
                    List<JSONTreeNode> ddValues = new ArrayList<>();
                    //TODO 未知
                    Integer valueLength = -1;
                    //构建字典值   多数据则值获取拆分后值的长度
                    for (int i = 0; i < config.size(); i++) {
                        JSONObject field = config.getJSONObject(i);
                        //字段类型
                        String fieldType = field.getString("code");
                        //
                        String fieldName = field.getString("value");
                        //字段值
                        String value = map.get(fieldName) + "";
                        //将值拼接操作
                        if (isMore) {
                            if (DDSQLListType.ID_S.equals(fieldStandard) && DDSQLListType.ID.equals(fieldType)) {
                                valueLength = value.split(fieldSplitName.get(fieldStandard)).length;
                            } else if (DDSQLListType.NAME_S.equals(fieldStandard) && DDSQLListType.NAME.equals(fieldType)) {
                                valueLength = value.split(fieldSplitName.get(fieldStandard)).length;
                            } else if (DDSQLListType.CODE_S.equals(fieldStandard) && DDSQLListType.CODE.equals(fieldType)) {
                                valueLength = value.split(fieldSplitName.get(fieldStandard)).length;
                            } else if (DDSQLListType.ICONCLS_S.equals(fieldStandard) && DDSQLListType.ICONCLS.equals(fieldType)) {
                                valueLength = value.split(fieldSplitName.get(fieldStandard)).length;
                            }
                            if (valueLength > 0) {
                                break;
                            }
                        } else {
                            if (DDSQLListType.ID.equals(fieldType)) {
                                ddValue.setId(value);
                            } else if (DDSQLListType.NAME.equals(fieldType)) {
                                ddValue.setText(value);
                            } else if (DDSQLListType.CODE.equals(fieldType)) {
                                ddValue.setCode(value);
                            } else if (DDSQLListType.ICONCLS.equals(fieldType)) {
                                ddValue.setIconCls(value);
                            }
                        }
                    }

                    if (isMore && valueLength > 0) {
                        for (Integer i = 0; i < valueLength; i++) {
                            JSONTreeNode splitValue = new JSONTreeNode();

                            for (int j = 0; j < config.size(); j++) {
                                JSONObject field = config.getJSONObject(j);
                                //字段类型
                                String fieldType = field.getString("code");
                                //
                                String fieldName = field.getString("value");
                                //字段值
                                String value = map.get(fieldName) + "";
                                String[] valueArray = new String[]{};
                                if (StringUtil.isNotEmpty(fieldSplitName.get(fieldType + "_S"))) {
                                    valueArray = value.split(fieldSplitName.get(fieldType + "_S"));
                                    if (valueArray.length != valueLength) {
                                        logger.error("发现字典中字段【" + fieldType + "】值拆分长度不一致,请检查!");
                                        throw new PlatformException("发现字典中字段【" + fieldType + "】值拆分长度不一致,请检查!", PlatformExceptionEnum.JE_CORE_DIC_CHECKITEM_ERROR, new Object[]{obj});
                                    }
                                    //没有定义分割
                                }
                                if (DDSQLListType.ID.equals(fieldType)) {
                                    if (StringUtil.isNotEmpty(fieldSplitName.get(DDSQLListType.ID_S))) {
                                        //如果配置了id，需要添加_字段CODE用于回显
                                        String echoCode = "";
                                        if (!com.google.common.base.Strings.isNullOrEmpty(obj.getString("nodeInfo"))) {
                                            echoCode = "_" + obj.getString("nodeInfo");
                                        }
                                        splitValue.setId(valueArray[i] + echoCode);
                                    } else {
                                        splitValue.setId(value);
                                    }
                                } else if (DDSQLListType.NAME.equals(fieldType)) {
                                    if (StringUtil.isNotEmpty(fieldSplitName.get(DDSQLListType.NAME_S))) {
                                        splitValue.setText(valueArray[i]);
                                    } else {
                                        splitValue.setText(value);
                                    }
                                } else if (DDSQLListType.CODE.equals(fieldType)) {
                                    if (StringUtil.isNotEmpty(fieldSplitName.get(DDSQLListType.CODE_S))) {
                                        splitValue.setCode(valueArray[i]);
                                    } else {
                                        splitValue.setCode(value);
                                    }
                                } else if (DDSQLListType.ICONCLS.equals(fieldType)) {
                                    if (StringUtil.isNotEmpty(fieldSplitName.get(DDSQLListType.ICONCLS_S))) {
                                        splitValue.setIconCls(valueArray[i]);
                                    } else {
                                        splitValue.setIconCls(value);
                                    }
                                }
                                if (StringUtil.isNotEmpty(nodeInfo)) {
                                    splitValue.setNodeInfo(nodeInfo);
                                    splitValue.setParent("ROOT_" + nodeInfo);
                                } else {
                                    splitValue.setParent("ROOT");
                                }
                                splitValue.setLeaf(true);
                                splitValue.setBean(map);
                            }
                            ddValues.add(splitValue);
                        }
                        jsonTreeNodeList.addAll(ddValues);
                    } else {
                        if (StringUtil.isNotEmpty(nodeInfo)) {
                            ddValue.setNodeInfo(nodeInfo);
                            ddValue.setParent("ROOT_" + nodeInfo);
                        } else {
                            ddValue.setParent("ROOT");
                        }
                        ddValue.setBean(map);
                        ddValue.setLeaf(true);
                        jsonTreeNodeList.add(ddValue);
                    }
                }
                //配置根节点
                JSONTreeNode rootNode = new JSONTreeNode();
                rootNode.setText(ddName);
                rootNode.setParent("ROOT");
                if (StringUtil.isNotEmpty(nodeInfo)) {
                    rootNode.setNodeInfo(nodeInfo);
                    rootNode.setId("ROOT_" + nodeInfo);// + rootNode.getId());
                } else {
                    rootNode.setId("ROOT");// + rootNode.getId());
                }
                rootNode.setIconCls("jeicon jeicon-tree-query");
                if (onlyItem) {
                    array.addAll(jsonTreeNodeList);
                } else {
                    rootNode.getChildren().addAll(jsonTreeNodeList);
                    array.add(rootNode);
                }
            } else {
                array.add(emptyRoot);
                logger.error("SQL动态字段信息错误,字典:【" + ddCode + "】参数值:【" + sql + "】,配置：【" + sqlConfig + "】!");
            }
        } else if (DDType.LIST.equalsIgnoreCase(ddType) || DDType.TREE.equalsIgnoreCase(ddType)) {
            //手动添加字典：列表字典 树形字典
            // 是否自维护字典
            if ("1".equals(obj.getString("zwfFlag"))) {
                //维护字典
                tableName = "JE_JTGS_DICTIONARYITEM";
            } else {
                // 普通字典
                tableName = "JE_CORE_DICTIONARYITEM";
            }
            //获取资源表信息
            DynaBean table = BeanUtils.getInstance().getResourceTable(tableName);
            if (table == null) {
                array.add(emptyRoot);
                return array;
            }

            //资源表树形字段配置
            JSONTreeNode template = BeanUtils.getInstance().buildJSONTreeNodeTemplate((List<DynaBean>) table.get(BeanUtils.KEY_TABLE_COLUMNS));
            //使用英文
            if ("JE_CORE_DICTIONARYITEM".equals(tableName) && en) {
                template.setText("DICTIONARYITEM_ITEMNAME_EN");
                template.setEnField("DICTIONARYITEM_ITEMNAME");
            }


            // 增加条件字典ID
            query.addCustom("DICTIONARYITEM_DICTIONARY_ID", ConditionEnum.EQ, dictionary.getStr("JE_CORE_DICTIONARY_ID"));

            // 是否自维护字典
            if ("1".equals(obj.getString("zwfFlag"))) {
                // 自维护字典
                query.addCustom("DICTIONARYITEM_DICTIONARY_ID", ConditionEnum.EQ, dictionary.getStr("JE_CORE_DICTIONARY_ID"));
                //查找根节点
                if ("1".equals(isRoot)) {
                    //增加条件租户ID
                    query.addCustom("SY_ZHID", ConditionEnum.EQ, SecurityUserHolder.getCurrentUser().getZhId());
                    //构建查询根节点
                    DynaBean beanRoot = metaService.selectOne(tableName, query.buildWrapper().eq("SY_NODETYPE", "ROOT"),
                            "JE_JTGS_DICTIONARYITEM_ID,SY_NODETYPE");
                    rootId = beanRoot.getStr("JE_JTGS_DICTIONARYITEM_ID");
                }
            } else {
                // 普通字典
                // 查找根节点
                if ("1".equals(isRoot)) {
                    if (ConstantVars.TREE_ROOT.equals(rootId)) {
                        rootId = dictionary.getStr("DICTIONARY_ITEMROOT_ID");
                    }
                }
                if (en) {
                    template.setText("DICTIONARYITEM_ITEMNAME_EN");
                    template.setEnField("DICTIONARYITEM_ITEMNAME");
                }
            }
            query.addCustom("SY_FLAG", ConditionEnum.EQ, "1");

            //过滤平台核心
            String[] tables = JepfCacheManager.getCacheValue("SY_JECORETABLES").split(",");
            if (ArrayUtils.contains(tables, tableName)) {
                //SY_JESYS='1'
                Condition condition = query.findCondition("SY_JESYS", "1");
                if ("1".equals(WebUtils.getSysVar("SY_JECORE"))) {
                    //SY_JECORE!='1'
                    Condition sy_jecore = new Condition("SY_JECORE", ConditionEnum.NE.getType(), "1");
                    //SY_JECORE IS NULL
                    Condition sy_jecore_null = new Condition("SY_JECORE", ConditionEnum.IS_NULL.getType(), "", "OR");
                    if (condition != null) {
                        //"SY_JESYS='1'", "(SY_JESYS='1' OR (SY_JECORE!='1' OR SY_JECORE IS NULL))"
                        condition.setCode("");
                        condition.setType("or".equalsIgnoreCase(condition.getCn()) ? ConditionEnum.OR.getType() : ConditionEnum.AND.getType());
                        Condition sy_jesys = new Condition("SY_JESYS", ConditionEnum.EQ.getType(), "1");
                        Condition conditionOr = new Condition("", ConditionEnum.OR.getType(), Lists.newArrayList(sy_jecore, sy_jecore_null));
                        condition.setValue(Lists.newArrayList(sy_jesys, conditionOr));
                    } else {
                        //" AND (SY_JECORE!='1' OR SY_JECORE IS NULL)";
                        query.addCustom("", ConditionEnum.AND, Lists.newArrayList(sy_jecore, sy_jecore_null));
                    }
                } else if (condition != null) {
                    // querySql = querySql.replace("SY_JESYS='1'", "1=1");
                    query.getCustom().remove(condition);
                }
            }

            ConditionsWrapper selectDic = query.buildWrapper();

            // 添加字典配置sql
            if (StringUtil.isNotEmpty(ddWhereSql)) {
                //formatSqlParameter 替换Sql中的系统变量 非预处理赋值
                selectDic.apply(QueryBuilder.formatSqlParameter(ddWhereSql));
            }

            //排序条件
            selectDic.getParameter().put("orderSql", orderSql);

            List<JSONTreeNode> jsonTreeNodeList = loadTreeNodeList(rootId, tableName, template, selectDic);

            for (JSONTreeNode node : jsonTreeNodeList) {
                if (node.getId().equals(rootId)) {
                    node.setText(ddName);
                    node.setIconCls("jeicon jeicon-tree-query");
                    node.setParent("ROOT");
                    node.setDisabled("1");
                    if (StringUtil.isNotEmpty(nodeInfo)) {
                        node.setNodeInfo(nodeInfo);
                        node.setId(node.getId() + "_" + nodeInfo);
                    }
                } else {
                    if (StringUtil.isNotEmpty(nodeInfo)) {
                        node.setNodeInfo(nodeInfo);
                        node.setId(node.getId() + "_" + nodeInfo);
                        node.setParent(node.getParent() + "_" + nodeInfo);
                    }
                }
                if ("JE_CORE_DICTIONARYITEM".equals(tableName)) {
                    node.setBean(new HashMap<>());
                }
            }
            if (StringUtil.isNotEmpty(nodeInfo)) {
                rootId = rootId + "_" + nodeInfo;
            }
            JSONTreeNode rootNode = buildJSONNewTree(jsonTreeNodeList, rootId);
            rootNode.setText(ddName);
            rootNode.setParent("ROOT");
            rootNode.setIconCls("jeicon jeicon-tree-query");
//            if ("1".equals(dataCache) ) {
//                DicCacheManager.putTreeCache(key, rootNode);
//            }
            if (onlyItem) {
                array.addAll(rootNode.getChildren());
            } else {
                array.add(rootNode);
            }
        } else if (DDType.DYNA_TREE.equalsIgnoreCase(ddType)) {

            if ("1".equalsIgnoreCase(moreRoot)) {
                //查询根节点
                ConditionsWrapper selectRoot = query.buildWrapper().eq("SY_NODETYPE", "ROOT")
                        .apply(StringUtil.isNotEmpty(ddWhereSql), QueryBuilder.formatSqlParameter(ddWhereSql));

                //根节点
                List<DynaBean> select = metaService.select(tableName, selectRoot);
                if (select.size() == 1) {
                    DynaBean rootBean = select.get(0);
                    rootId = rootBean.getStr(BeanUtils.getInstance().getPKeyFieldNames(tableName));
                }
//                if (rootBean != null) {
//                    rootId = rootBean.getStr(BeanUtils.getInstance().getPKeyFieldNames(tableName));
//                }
            }
            //获取资源表信息
            DynaBean table = BeanUtils.getInstance().getResourceTable(tableName);
            if (table == null) {
                array.add(emptyRoot);
                return array;
            }

            //资源表树形字段配置
            JSONTreeNode template = BeanUtils.getInstance().buildJSONTreeNodeTemplate((List<DynaBean>) table.get(BeanUtils.KEY_TABLE_COLUMNS));
            //RBAC相关树形表表特殊处理
            String[] rbacTables = new String[]{"JE_CORE_DEPARTMENT", "JE_CORE_ROLE", "JE_CORE_SENTRY", "JE_CORE_VDEPTUSER", "JE_CORE_VROLEUSER", "JE_CORE_VSENTRYUSER", "JE_CORE_ROLEGROUP"};
            if (ArrayUtils.contains(rbacTables, tableName)) {

                //SAAS模式条件
                if (WebUtils.isSaas()) {
                    //查找ZHID条件
                    Condition findZHID = query.findCondition("ZHID");
                    if (findZHID == null) {
                        findZHID = query.findCondition("SY_ZHID");
                    }

                    if (findZHID == null) {
                        if ("JE_CORE_ROLE".equalsIgnoreCase(tableName)) {

                            //TODO 原逻辑可能出错
                            if (query.findCondition("ROLERANK", "SYS") != null) {

                            } else if ("SYSTEM".equals(currentUser.getZhId())) {
                                query.addCustom("ROLERANK", ConditionEnum.EQ, "SYS");
                                query.addCustom("ZHID", ConditionEnum.EQ, currentUser.getZhId());
                            } else {
                                query.addCustom("ZHID", ConditionEnum.EQ, currentUser.getZhId());
                            }
                        } else if ("JE_CORE_DEPARTMENT".equals(tableName)) {
                            //" AND( ZHID='" + currentUser.getZhId() + "' or DEPTID ='ROOT')"
                            Condition zhid = new Condition("ZHID", ConditionEnum.EQ.getType(), currentUser.getZhId());
                            Condition deptid = new Condition("DEPTID", ConditionEnum.EQ.getType(), "ROOT", "OR");
                            Condition conditionAnd = new Condition();
                            conditionAnd.setType(ConditionEnum.AND.getType());
                            conditionAnd.setValue(Lists.newArrayList(zhid, deptid));
                            query.getCustom().add(conditionAnd);
                        } else if ("JE_CORE_ROLEGROUP".equalsIgnoreCase(tableName)) {
                            query.addCustom("SY_ZHID", ConditionEnum.EQ, currentUser.getZhId());
                        } else {
                            query.addCustom("ZHID", ConditionEnum.EQ, currentUser.getZhId());
                        }
                    }
                } else {
                    if ("JE_CORE_ROLE".equals(tableName)) {
                        if (query.findCondition("ROLERANK", "SYS") == null) {
                            query.getCustom().add(new Condition("ROLERANK", ConditionEnum.EQ.getType(), "SYS"));
                        }
                    }
                    if (obj.containsKey("params")) {
                        JSONObject varObj = obj.getJSONObject("params");
                        if (varObj.containsKey("ADMINPERM") && "1".equals(varObj.getString("ADMINPERM"))) {
                            //Admin权限sql
                            ddWhereSql += adminPermManager.getQuerySql(tableName);
                        }
                    }
                }
            }

            //过滤平台核心
            String[] tables = JepfCacheManager.getCacheValue("SY_JECORETABLES").split(",");
            if (ArrayUtils.contains(tables, tableName)) {
                //SY_JESYS='1'
                Condition condition = query.findCondition("SY_JESYS", "1");
                if ("1".equals(WebUtils.getSysVar("SY_JECORE"))) {
                    //SY_JECORE!='1'
                    Condition sy_jecore = new Condition("SY_JECORE", ConditionEnum.NE.getType(), "1");
                    //SY_JECORE IS NULL
                    Condition sy_jecore_null = new Condition("SY_JECORE", ConditionEnum.IS_NULL.getType(), "", "OR");
                    if (condition != null) {
                        //"SY_JESYS='1'", "(SY_JESYS='1' OR (SY_JECORE!='1' OR SY_JECORE IS NULL))"
                        condition.setCode("");
                        condition.setType("or".equalsIgnoreCase(condition.getCn()) ? ConditionEnum.OR.getType() : ConditionEnum.AND.getType());
                        Condition sy_jesys = new Condition("SY_JESYS", ConditionEnum.EQ.getType(), "1");
                        Condition conditionOr = new Condition("", ConditionEnum.OR.getType(), Lists.newArrayList(sy_jecore, sy_jecore_null));
                        condition.setValue(Lists.newArrayList(sy_jesys, conditionOr));
                    } else {
                        //" AND (SY_JECORE!='1' OR SY_JECORE IS NULL)";
                        query.addCustom("", ConditionEnum.AND, Lists.newArrayList(sy_jecore, sy_jecore_null));
                    }
                } else if (condition != null) {
                    // querySql = querySql.replace("SY_JESYS='1'", "1=1");
                    query.getCustom().remove(condition);
                }
            }


            //构建查询条件
            ConditionsWrapper selectDic = query.buildWrapper();
            // 添加字典配置sql
            if (StringUtil.isNotEmpty(ddWhereSql)) {
                //formatSqlParameter 替换Sql中的系统变量 非预处理赋值
                selectDic.apply(QueryBuilder.formatSqlParameter(ddWhereSql));
            }

            //获取Admin权限sql
            String queryTableCode = obj.getString("queryTableCode");
            if (StringUtils.isNotBlank(queryTableCode)) {
                String adminPermSql = adminPermManager.getQuerySql(queryTableCode);
                if (StringUtils.isNotBlank(adminPermSql)) {
                    final String sql = adminPermSql;
                    selectDic.and(i -> i.apply(QueryBuilder.trimSql(sql)));
                }
            }

            //排序条件
            selectDic.getParameter().put("orderSql", orderSql);

            List<JSONTreeNode> jsonTreeNodeList = loadTreeNodeList(rootId, tableName, template, selectDic);

            for (JSONTreeNode node : jsonTreeNodeList) {
                if (node.getId().equals(rootId)) {
                    node.setText(ddName);
                    node.setIconCls("jeicon jeicon-tree-query");
                    node.setParent("ROOT");
                    node.setDisabled("1");
                    if (StringUtil.isNotEmpty(nodeInfo)) {
                        node.setNodeInfo(nodeInfo);
                        node.setId(node.getId() + "_" + nodeInfo);
                    }
                } else {
                    if (StringUtil.isNotEmpty(nodeInfo)) {
                        node.setNodeInfo(nodeInfo);
                        node.setId(node.getId() + "_" + nodeInfo);
                        node.setParent(node.getParent() + "_" + nodeInfo);
                    }
                }
            }
            if (StringUtil.isNotEmpty(nodeInfo)) {
                rootId = rootId + "_" + nodeInfo;
            }
            JSONTreeNode rootNode = buildJSONNewTree(jsonTreeNodeList, rootId);
            if (onlyItem) {
                array.addAll(rootNode.getChildren());
            } else if (emptyRoot.getId().equals(rootNode.getId())) {
                array.add(rootNode);
            } else {
                rootNode.setParent("ROOT");
                try {
                    rootNode.setText(rootNode.getBean().get(template.getText()).toString());
                } catch (Exception e) {
                    logger.debug(e.getMessage());
                }
                rootNode.setDisabled("0");
                rootNode.setIconCls("");
                emptyRoot.getChildren().add(rootNode);
                array.add(emptyRoot);
            }
        } else {
            array.add(emptyRoot);
            logger.error("传入的字典类型出错,字典:【" + ddCode + "】!");
        }
        return array;
    }

    public JSONTreeNode buildJSONNewTree(List<JSONTreeNode> lists, String rootId) {
        JSONTreeNode root = new JSONTreeNode();
        for (JSONTreeNode node : lists) { //当前循环这个集合每一个元素
            if (node.getParent() == null || "".equals(node.getParent()) || rootId.equals(node.getId())) {
                root = node;
                lists.remove(node);
                break;
            }
        }
        createTreeChildren(lists, root);
        return root;
    }

    /**
     * 递归方法
     *
     * @param childrens
     * @param root
     */
//    public void createTreeChildren(List<JSONTreeNode> childrens, JSONTreeNode root) {
//        String parentId = root.getId();
//        for (int i = 0; i < childrens.size(); i++) {
//            JSONTreeNode node = childrens.get(i);
//            if (parentId.equals(node.getParent())) {
//                root.getChildren().add(node);
//                //当前不能删除节点，因为孩子引用与它， 递归回来，坐标失效
////                if (node.isLeaf() == false) {
//                createTreeChildren(childrens, node);
////                }
//            }
//            if (i == childrens.size() - 1) {
//                if (root.getChildren().size() > 0) {
//                    root.setLeaf(false);
//                }
//                return;
//            }
//        }
//    }
    public void createTreeChildren(List<JSONTreeNode> childrens, JSONTreeNode root) {
        String parentId = root.getId();
        for (int y = 0; y < childrens.size(); y++) {
            JSONTreeNode node = childrens.get(y);
            if (parentId.equals(node.getParent())) {
                root.getChildren().add(node);
            }
        }
        for (int i = 0; i < childrens.size(); i++) {
            JSONTreeNode node = childrens.get(i);
            parentId = node.getId();
            for (int x = 0; x < childrens.size(); x++) {
                JSONTreeNode node2 = childrens.get(x);
                if (parentId.equals(node2.getParent())) {
                    node.getChildren().add(node2);
//                    createTreeChildren(childrens, node);
                }
            }
        }
    }

    @Override
    public List<JSONTreeNode> loadAsyncTreeNodeList(String rootId, String tableName, JSONTreeNode template, ConditionsWrapper where, Boolean isRoot, Boolean onlyWhereSql) {

        //where 条件
        if (!onlyWhereSql) {
            if ("1".equals(isRoot)) {
                where.and(i -> {
                    i.eq(template.getParent(), rootId).or().eq(template.getId(), rootId);
                });
            } else {
                where.eq(template.getParent(), rootId);
            }
        }
        List<JSONTreeNode> jsonTreeNodes = loadTreeNodeList(rootId, tableName, template, where, null, null);
        for (JSONTreeNode node : jsonTreeNodes) {
            node.setAsync(true);
        }
        return jsonTreeNodes;
    }

    public List<JSONTreeNode> loadTreeNodeList(String rootId, String tableName, JSONTreeNode template, ConditionsWrapper where) {
        ConditionsWrapper builder = ConditionsWrapper.builder();
        //复制参数
        builder.putAll(where.getParameter());
        //and (nodePath like '%rootId%' and (whereSql)) or id = rootId
        String sql = QueryBuilder.trimSql(where.getSql());
        builder.and(i -> {
            i.like(template.getNodePath(), rootId)
                    //语句不为空时拼接
                    .and(j -> j.apply(StringUtils.isNotBlank(sql), sql));
        }).or().eq(template.getId(), rootId);
        return loadTreeNodeList(rootId, tableName, template, builder, null, null);
    }

    @Override
    public List<JSONTreeNode> loadTreeNodeList(String rootId, String tableName, JSONTreeNode template, ConditionsWrapper where, List<String> includeIds, String[] beanFields) {
        List<JSONTreeNode> list = new ArrayList<>();
        if (TreeUtil.verify(template)) {

            //拼接sql
            StringBuilder filedSql = new StringBuilder();
            filedSql.append(" select ").append(template.getId()).append(",").append(template.getCode()).append(",").append(template.getText()).append(",").append(template.getParent());
            // 英文名称
            if (StringUtil.isNotEmpty(template.getEnField())) {
                filedSql.append(",").append(template.getEnField());
            }
            if (StringUtil.isNotEmpty(template.getParentText())) {
                filedSql.append(",").append(template.getParentText());
            }
            // 节点类型
            if (StringUtil.isNotEmpty(template.getNodeType())) {
                filedSql.append(",").append(template.getNodeType());
            }
            // 节点信息
            if (StringUtil.isNotEmpty(template.getNodeInfo())) {
                filedSql.append(",").append(template.getNodeInfo());
            }
            // 节点信息类型
            if (StringUtil.isNotEmpty(template.getNodeInfoType())) {
                filedSql.append(",").append(template.getNodeInfoType());
            }
            if (StringUtil.isNotEmpty(template.getLayer())) {
                filedSql.append(",").append(template.getLayer());
            }
            // 图标图片地址
            if (StringUtil.isNotEmpty(template.getIcon())) {
                filedSql.append(",").append(template.getIcon());
            }
            // 图标样式
            if (StringUtil.isNotEmpty(template.getIconCls())) {
                filedSql.append(",").append(template.getIconCls());
            }
            //是否禁用
            if (StringUtil.isNotEmpty(template.getDisabled())) {
                filedSql.append(",").append(template.getDisabled());
            }
            //树形路径
            if (StringUtil.isNotEmpty(template.getNodePath())) {
                filedSql.append(",").append(template.getNodePath());
            }
            //树形父节点路径
            if (StringUtil.isNotEmpty(template.getParentPath())) {
                filedSql.append(",").append(template.getParentPath());
            }
            //链接
            if (StringUtil.isNotEmpty(template.getHref())) {
                filedSql.append(",").append(template.getHref());
            }
            //链接目标
            if (StringUtil.isNotEmpty(template.getHrefTarget())) {
                filedSql.append(",").append(template.getHrefTarget());
            }
            //描述
            if (StringUtil.isNotEmpty(template.getDescription())) {
                filedSql.append(",").append(template.getDescription());
            }
            if (StringUtil.isNotEmpty(template.getOrderIndex())) {
                filedSql.append(",").append(template.getOrderIndex());
            }
            if (StringUtil.isNotEmpty(template.getTreeOrderIndex())) {
                filedSql.append(",").append(template.getTreeOrderIndex());
            }
            if (StringUtil.isNotEmpty(template.getFieldCodes())) {
                filedSql.append(template.getFieldCodes());
            }
            filedSql.append(" FROM ").append(tableName).append(" where ");

            //创建查询
            ConditionsWrapper select = ConditionsWrapper.builder().apply(filedSql.toString());
            //加入传过来的where条件和预处理参数
            select.apply(QueryBuilder.trimSql(where.getSql())).putAll(where.getParameter());
            //orderSql
            String orderSql = (String) where.getParameter().getOrDefault("orderSql", "");
            if (StringUtils.isBlank(orderSql)) {
                orderSql = " ORDER BY " + template.getParent() + " asc";
                if (StringUtil.isNotEmpty(template.getOrderIndex())) {
                    orderSql += ", " + template.getOrderIndex() + " asc";
                }
            }
            //添加order
            select.apply(orderSql);

            //执行查询
            List<Map<String, Object>> treeItems = metaService.selectSql(select);

            //遍历结果构建树形节点对象
            treeItems.forEach(record -> {

                //主键
                String nodeId = (String) record.get(template.getId());
                //排除不在指定节点内的数据
                if (includeIds != null && includeIds.size() > 0 && !includeIds.contains(nodeId)) {
                    return;
                }
                JSONTreeNode node = new JSONTreeNode();
                node.setId(nodeId);
                //名称
                node.setText((String) record.get(template.getText()));
                //编码
                node.setCode((String) record.get(template.getCode()));
                //父节点
                node.setParent((String) record.get(template.getParent()));
                //节点信息
                if (StringUtil.isNotEmpty(template.getNodeInfo())) {
                    node.setNodeInfo(StringUtil.getClobValue(record.get(template.getNodeInfo())));
                }
                //英文名称
                if (StringUtil.isNotEmpty(template.getEnField())) {
                    node.setEnField(record.get(template.getEnField()) + "");
                }
                //父节点名称
                if (StringUtil.isNotEmpty(template.getParentText())) {
                    node.setParentText(record.get(template.getParentText()) + "");
                }
                //节点信息类型
                if (StringUtil.isNotEmpty(template.getNodeInfoType())) {
                    node.setNodeInfoType(record.get(template.getNodeInfoType()) + "");
                }
                //是否叶子
                if (StringUtil.isNotEmpty(template.getNodeType())) {
                    node.setLeaf(NodeType.LEAF.equalsIgnoreCase(record.get(template.getNodeType()) + ""));
                    node.setNodeType(record.get(template.getNodeType()) + "");
                }
                if (StringUtil.isNotEmpty(template.getLayer())) {
                    node.setLayer(record.get(template.getLayer()) + "");
                }
                //图标图片地址
                if (StringUtil.isNotEmpty(template.getIcon())) {
                    node.setIcon(record.get(template.getIcon()) + "");
                }
                //图标样式
                if (StringUtil.isNotEmpty(template.getIconCls())) {
                    node.setIconCls(record.get(template.getIconCls()) + "");
                }
                //是否禁用
                if (StringUtil.isNotEmpty(template.getDisabled())) {
                    if (StringUtil.isEmpty(record.get(template.getDisabled()))) {
                        node.setDisabled("0");
                    } else {
                        node.setDisabled(record.get(template.getDisabled()) + "");
                    }
                } else {
                    node.setDisabled("0");
                }
                //树形路径
                if (StringUtil.isNotEmpty(template.getNodePath())) {
                    node.setNodePath(record.get(template.getNodePath()) + "");
                }
                //树形父节点路径
                if (StringUtil.isNotEmpty(template.getParentPath())) {
                    node.setParentPath(record.get(template.getParentPath()) + "");
                }
                //链接
                if (StringUtil.isNotEmpty(template.getHref())) {
                    node.setHref(record.get(template.getHref()) + "");
                }
                //链接目标
                if (StringUtil.isNotEmpty(template.getHrefTarget())) {
                    node.setHrefTarget(record.get(template.getHrefTarget()) + "");
                }
                //描述
                if (StringUtil.isNotEmpty(template.getDescription())) {
                    node.setDescription(StringUtil.getClobValue(record.get(template.getDescription())));
                }
                //排序
                if (StringUtil.isNotEmpty(template.getOrderIndex())) {
                    node.setOrderIndex(record.get(template.getOrderIndex()) + "");
                }
                if (StringUtil.isNotEmpty(template.getTreeOrderIndex())) {
                    node.setTreeOrderIndex(record.get(template.getTreeOrderIndex()) + "");
                }

                //保留指定字段
                if (beanFields != null && beanFields.length > 0) {
                    List<String> fieldList = Arrays.asList(beanFields);
                    Set<String> keySet = record.keySet();
                    for (String key : keySet) {
                        if (!fieldList.contains(key)) {
                            record.remove(key);
                        }
                        ;
                    }

                }
                //如果是oracle则单独处理
                if (PCDaoTemplateImpl.DBNAME.equals(ConstantVars.STR_ORACLE)) {
                    record.forEach((key, val) -> {
                        if (val == null) {
                            record.put(key, "");
                        } else if (val instanceof Clob) {
                            record.put(key, StringUtil.getClobValue(record.get(key)));
                        }
                    });
                }
                node.setBean(record);
                list.add(node);
            });
        }
        return list;
    }

    @Override
    public List<DictionaryItemVo> buildChildrenList(DynaBean dic, Query query, String itemCode, boolean en, boolean zwfFlag) {

        ConditionsWrapper wrapper = ConditionsWrapper.builder()
                .eq("SY_FLAG", "1").ne("SY_NODETYPE", "ROOT")
                .eq("DICTIONARYITEM_DICTIONARY_ID", dic.getStr("JE_CORE_DICTIONARY_ID"))
                //指定字典项
                .eq(StringUtil.isNotEmpty(itemCode), "DICTIONARYITEM_ITEMCODE", itemCode)
                //自维护字典
                .eq(zwfFlag, "SY_ZHID", SecurityUserHolder.getCurrentUser().getZhId());

        //添加where条件
        query.buildWrapper(wrapper);
        //添加order条件
        String orderSql = query.buildOrder();
        if (StringUtils.isNotEmpty(orderSql)) {
            wrapper.apply(" ORDER BY ").apply(orderSql);
        } else {
            wrapper.apply(" ORDER BY SY_ORDERINDEX");
        }

        //字典表名
        String tableCode = "JE_CORE_DICTIONARYITEM";
        //自维护字典
        if (zwfFlag) {
            tableCode = "JE_JTGS_DICTIONARYITEM";
        }

        //查询字典项
        List<DynaBean> items = metaService.select(tableCode, wrapper);
        List<DictionaryItemVo> voList = new ArrayList<>();
        for (int i = 0; i < items.size(); i++) {
            DynaBean item = items.get(i);
            DictionaryItemVo vo = new DictionaryItemVo();
            //自维护字典
            if (zwfFlag) {
                vo.setId(item.getStr("JE_JTGS_DICTIONARYITEM_ID"));
            } else {
                vo.setId(item.getStr("JE_CORE_DICTIONARYITEM_ID"));
            }
            //国际化
            if (en) {
                vo.setText(item.getStr("DICTIONARYITEM_ITEMNAME_EN"));
            }
            vo.setCode(item.getStr("DICTIONARYITEM_ITEMCODE"));
            vo.setIcon(item.getStr("DICTIONARYITEM_REFPHOTO"));
            vo.setText(item.getStr("DICTIONARYITEM_ITEMNAME"));
            vo.setTextColor(item.getStr("DICTIONARYITEM_FONTCOLOR"));
            vo.setIconCls(item.getStr("DICTIONARYITEM_ICONCLS"));
            vo.setBackgroundColor(item.getStr("DICTIONARYITEM_BACKGROUNDCOLOR"));
            voList.add(vo);
        }
        return voList;
    }

    @Override
    public List<JSONTreeNode> loadLinkTree(String ddCode, String parentId, String parentCode, String rootId, String paramStr, boolean zwfFlag, boolean en, Query query) {

        if (StringUtil.isEmpty(rootId)) {
            rootId = ConstantVars.TREE_ROOT;
        }

        List<JSONTreeNode> array = new ArrayList<>();

        //查询字典主表信息
        DynaBean dictionary = DicInfoCacheManager.getCacheValue(ddCode);
        EndUser currentUser = SecurityUserHolder.getCurrentUser();
        if (dictionary == null) {
            dictionary = metaService.selectOne("JE_CORE_DICTIONARY", ConditionsWrapper.builder().eq("DICTIONARY_DDCODE", ddCode));
        }
        if (dictionary == null) {
            throw new PlatformException("未找到数据字典：" + ddCode + "!", PlatformExceptionEnum.JE_CORE_DIC_UNKOWN_ERROR);
        }

        //字典配置项
        String ddType = dictionary.getStr("DICTIONARY_DDTYPE");
        String ddWhereSql = dictionary.getStr("DICTIONARY_WHERESQL", "");
        String ddOrderSql = dictionary.getStr("DICTIONARY_ORDERSQL", "");
        String tableName = dictionary.getStr("DICTIONARY_CLASSNAME");

        //前端sql条件转换
        //排序条件
        String orderSql = "";
        if (!query.getOrder().isEmpty()) {
            orderSql = " ORDER BY " + query.buildOrder();
        } else if (StringUtils.isNotBlank(ddOrderSql)) {
            orderSql = ddOrderSql;
        }

        if (DDType.CUSTOM.equalsIgnoreCase(ddType)) {
            //自定义后端
            // 无 ddWhereSql ddOrderSql
            String beanName = dictionary.getStr("DICTIONARY_CLASS");
            String beanMethod = dictionary.getStr("DICTIONARY_METHOD");
            HashMap<String, String> params = new HashMap<String, String>();
            if (StringUtil.isNotEmpty(paramStr)) {
                JSONObject varObj = JSON.parseObject(paramStr);
                for (String key : (Set<String>) varObj.keySet()) {
                    params.put(key, varObj.getString(key));
                }
            }
            DicInfoVo dicInfoVo = new DicInfoVo();
            dicInfoVo.setParams(params);
            dicInfoVo.setRootId(rootId);
            dicInfoVo.setDdCode(ddCode);
            //不同
            dicInfoVo.setParentId(parentId);
            dicInfoVo.setParentCode(parentCode);
            if (!query.getOrder().isEmpty()) {
                dicInfoVo.setOrderSql(JSONObject.toJSONString(query.getOrder()));
            }
            if (!query.getCustom().isEmpty()) {
                dicInfoVo.setWhereSql(JSONObject.toJSONString(query.getCustom()));
            }
            dicInfoVo.setConditions(query.getCustom());
            Object bean = SpringContextHolder.getBean(beanName);
            JSONTreeNode rootNode = (JSONTreeNode) ReflectionUtils.getInstance().invokeMethod(bean, beanMethod, new Object[]{dicInfoVo});

            //不同
            array.addAll(rootNode.getChildren());
//            if (onlyItem) {
//                array.addAll(rootNode.getChildren());
//            } else {
//                array.add(rootNode);
//            }
        } else if (DDType.SQL_TREE.equalsIgnoreCase(ddType)) {
            //动态SQL树形字典

            //字典sql语句
            String sql = dictionary.getStr("DICTIONARY_SQL");
            //sql查询结果字段与树形字段配置
            String sqlConfig = dictionary.getStr("DICTIONARY_SQLCONFIG");
            if (StringUtil.isNotEmpty(sql) && StringUtil.isNotEmpty(sqlConfig)) {

                //树形字段配置
                JSONArray config = JSON.parseArray(sqlConfig);
                //参数集合
                JSONObject varObj = null;
                if (StringUtil.isNotEmpty(paramStr)) {
                    varObj = JSON.parseObject(paramStr);
                }

                //构建查询器
                ConditionsWrapper sqlSelect = ConditionsWrapper.builder();
                //添加字典语句和条件
                sqlSelect.apply(QueryBuilder.formatSqlParameter(sql))
                        .apply(StringUtil.isNotEmpty(ddWhereSql), QueryBuilder.formatSqlParameter(varObj, ddWhereSql));

                //级联条件
                String parentField = "";
                String codeField = "";
                String idField = "";
                //遍历树形字段配置
                for (int i = 0; i < config.size(); i++) {
                    JSONObject field = config.getJSONObject(i);
                    //树形字段类型
                    String fieldType = field.getString("code");
                    //树形字段对应结果集中字段名
                    String fieldName = field.getString("value");
                    if (StringUtil.isNotEmpty(fieldName)) {
                        if (TreeNodeType.ID.toString().equals(fieldType)) {
                            idField = fieldName;
                        } else if (TreeNodeType.CODE.toString().equals(fieldType)) {
                            codeField = fieldName;
                        } else if (TreeNodeType.PARENT.toString().equals(fieldType)) {
                            parentField = fieldName;
                        }
                    }
                }
                if (StringUtil.isNotEmpty(parentId)) {
                    //父节点条件
                    sqlSelect.eq(parentField, parentId);
                } else if (StringUtil.isNotEmpty(parentCode)) {
                    // 为了支持客户允许地区可以多选 yangzhi改于20191111
                    String[] split = parentCode.split(",");
                    String parentCodes = StringUtil.buildArrayToString(split);
                    List<Map<String, Object>> parents = metaService.selectSql(sqlSelect.clone().apply(" AND " + codeField + " in(" + parentCodes + ")"));
                    if (!parents.isEmpty()) {
                        ArrayList<String> ids = Lists.newArrayList();
                        for (Map<String, Object> bean : parents) {
                            ids.add(bean.getOrDefault(idField, "").toString());
                        }
                        //父节点条件
                        sqlSelect.in(parentField, ids);
//                        querySql += " AND " + parentField + " in(" + StringUtil.buildArrayToString(list) + ")";
                    } else {
                        throw new PlatformException("数据错误，根据CODE【" + parentCode + "】未找到父项值!", PlatformExceptionEnum.JE_CORE_DIC_UNKOWNPARENT_ERROR);
                    }
                } else {
                    //父节点条件
                    sqlSelect.eq(parentField, rootId);
                }

                //添加字典排序条件
                if (StringUtil.isEmpty(orderSql) && StringUtil.isNotEmpty(ddOrderSql)) {
                    orderSql = ddOrderSql;
                }
                sqlSelect.apply(QueryBuilder.formatSqlParameter(varObj, orderSql));

                //执行查询
                List<Map<String, Object>> list = metaService.selectSql(sqlSelect);

                //构建树形数据
                for (Map<String, Object> map : list) {
                    //初始化树形对象
                    JSONTreeNode node = new JSONTreeNode();
                    //遍历树形字段配置
                    for (int i = 0; i < config.size(); i++) {
                        JSONObject field = config.getJSONObject(i);
                        //树形字段类型
                        String fieldType = field.getString("code");
                        //树形字段对应结果集中字段名
                        String fieldName = field.getString("value");
                        if (StringUtil.isNotEmpty(fieldName)) {
                            //字段值
                            String value = map.get(fieldName) + "";
                            //根据不同fieldType放入对应字段
                            if (TreeNodeType.ID.toString().equals(fieldType)) {
                                node.setId(value);
                            } else if (TreeNodeType.TEXT.toString().equals(fieldType)) {
                                node.setText(value);
                            } else if (TreeNodeType.CODE.toString().equals(fieldType)) {
                                node.setCode(value);
                            } else if (TreeNodeType.PARENT.toString().equals(fieldType)) {
                                node.setParent(value);
                            } else if (TreeNodeType.NODETYPE.toString().equals(fieldType)) {
                                node.setNodeType(value);
                                node.setLeaf(NodeType.LEAF.equals(value));
                            } else if (TreeNodeType.NODEINFO.toString().equals(fieldType)) {
                                node.setNodeInfo(value);
                            } else if (TreeNodeType.NODEINFOTYPE.toString().equals(fieldType)) {
                                node.setNodeInfoType(value);
                            } else if (TreeNodeType.NODEPATH.toString().equals(fieldType)) {
                                node.setNodePath(value);
                            } else if (TreeNodeType.PARENTPATH.toString().equals(fieldType)) {
                                node.setParentPath(value);
                            } else if (TreeNodeType.DISABLED.toString().equals(fieldType)) {
                                node.setDisabled(value);
                            } else if (TreeNodeType.ORDERINDEX.toString().equals(fieldType)) {
                                if (StringUtil.isNotEmpty(value)) {
                                    node.setOrderIndex(value);
                                } else {
                                    node.setOrderIndex("0");
                                }
                            } else if (TreeNodeType.ICON.toString().equals(fieldType)) {
                                node.setIcon(value);
                            } else if (TreeNodeType.ICONCLS.toString().equals(fieldType)) {
                                node.setIconCls(value);
                            } else if (TreeNodeType.HREF.toString().equals(fieldType)) {
                                node.setHref(value);
                            } else if (TreeNodeType.HREFTARGET.toString().equals(fieldType)) {
                                node.setHrefTarget(value);
                            } else if (TreeNodeType.DESCRIPTION.toString().equals(fieldType)) {
                                node.setDescription(value);
                            }
                        }
                    }
                    //加入树形结果集
                    array.add(node);
                }
            } else {
                logger.error("SQL动态字段信息错误,字典:【" + ddCode + "】参数值:【" + sql + "】,配置：【" + sqlConfig + "】!");
            }
        } else if (DDType.LIST.equalsIgnoreCase(ddType) || DDType.TREE.equalsIgnoreCase(ddType)) {

            if (DDType.LIST.equalsIgnoreCase(ddType) || DDType.TREE.equalsIgnoreCase(ddType)) {

                //手动添加字典：列表字典 树形字典
                // 是否自维护字典
                if (zwfFlag) {
                    //维护字典
                    tableName = "JE_JTGS_DICTIONARYITEM";
                } else {
                    // 普通字典
                    tableName = "JE_CORE_DICTIONARYITEM";
                }
                //获取资源表信息
                DynaBean table = BeanUtils.getInstance().getResourceTable(tableName);
                if (table == null) {
                    return array;
                }

                // 增加条件字典ID
                query.addCustom("DICTIONARYITEM_DICTIONARY_ID", ConditionEnum.EQ, dictionary.getStr("JE_CORE_DICTIONARY_ID"));

                // 是否自维护字典
                if (zwfFlag) {
                    // 自维护字典
                    //查找根节点
                    //增加条件租户ID
                    query.addCustom("SY_ZHID", ConditionEnum.EQ, SecurityUserHolder.getCurrentUser().getZhId());
                    //构建查询根节点
                    DynaBean beanRoot = metaService.selectOne(tableName, query.buildWrapper().eq("SY_NODETYPE", "ROOT"),
                            "JE_JTGS_DICTIONARYITEM_ID,SY_NODETYPE");
                    rootId = beanRoot.getStr("JE_JTGS_DICTIONARYITEM_ID");
                } else {
                    // 普通字典
                    // 查找根节点
                    if (ConstantVars.TREE_ROOT.equals(rootId)) {
                        rootId = dictionary.getStr("DICTIONARY_ITEMROOT_ID");
                    }
                }
                query.addCustom("SY_FLAG", ConditionEnum.EQ, "1");
                orderSql = " ORDER BY SY_ORDERINDEX";

            }

            //RBAC相关树形表表特殊处理
            String[] rbacTables = new String[]{"JE_CORE_DEPARTMENT", "JE_CORE_ROLE", "JE_CORE_SENTRY", "JE_CORE_VDEPTUSER", "JE_CORE_VROLEUSER", "JE_CORE_VSENTRYUSER", "JE_CORE_ROLEGROUP"};
            if (ArrayUtils.contains(rbacTables, tableName)) {

                //SAAS模式条件
                if (WebUtils.isSaas()) {
                    //查找ZHID条件
                    Condition findZHID = query.findCondition("ZHID");
                    if (findZHID == null) {
                        findZHID = query.findCondition("SY_ZHID");
                    }

                    if (findZHID == null) {
                        if ("JE_CORE_ROLE".equalsIgnoreCase(tableName)) {

                            //TODO 原逻辑可能出错
                            if (query.findCondition("ROLERANK", "SYS") != null) {

                            } else if ("SYSTEM".equals(currentUser.getZhId())) {
                                query.addCustom("ROLERANK", ConditionEnum.EQ, "SYS");
                                query.addCustom("ZHID", ConditionEnum.EQ, currentUser.getZhId());
                            } else {
                                query.addCustom("ZHID", ConditionEnum.EQ, currentUser.getZhId());
                            }
                        } else if ("JE_CORE_DEPARTMENT".equals(tableName)) {
                            //" AND( ZHID='" + currentUser.getZhId() + "' or DEPTID ='ROOT')"
                            Condition zhid = new Condition("ZHID", ConditionEnum.EQ.getType(), currentUser.getZhId());
                            Condition deptid = new Condition("DEPTID", ConditionEnum.EQ.getType(), "ROOT", "OR");
                            Condition conditionAnd = new Condition();
                            conditionAnd.setType(ConditionEnum.AND.getType());
                            conditionAnd.setValue(Lists.newArrayList(zhid, deptid));
                            query.getCustom().add(conditionAnd);
                        } else if ("JE_CORE_ROLEGROUP".equalsIgnoreCase(tableName)) {
                            query.addCustom("SY_ZHID", ConditionEnum.EQ, currentUser.getZhId());
                        } else {
                            query.addCustom("ZHID", ConditionEnum.EQ, currentUser.getZhId());
                        }
                    }
                } else {
                    if ("JE_CORE_ROLE".equals(tableName)) {
                        if (query.findCondition("ROLERANK", "SYS") == null) {
                            query.getCustom().add(new Condition("ROLERANK", ConditionEnum.EQ.getType(), "SYS"));
                        }
                    }
                }
            }

            //过滤平台核心
            String[] tables = JepfCacheManager.getCacheValue("SY_JECORETABLES").split(",");
            if (ArrayUtils.contains(tables, tableName)) {
                //SY_JESYS='1'
                Condition condition = query.findCondition("SY_JESYS", "1");
                if ("1".equals(WebUtils.getSysVar("SY_JECORE"))) {
                    //SY_JECORE!='1'
                    Condition sy_jecore = new Condition("SY_JECORE", ConditionEnum.NE.getType(), "1");
                    //SY_JECORE IS NULL
                    Condition sy_jecore_null = new Condition("SY_JECORE", ConditionEnum.IS_NULL.getType(), "", "OR");
                    if (condition != null) {
                        //"SY_JESYS='1'", "(SY_JESYS='1' OR (SY_JECORE!='1' OR SY_JECORE IS NULL))"
                        condition.setCode("");
                        condition.setType("or".equalsIgnoreCase(condition.getCn()) ? ConditionEnum.OR.getType() : ConditionEnum.AND.getType());
                        Condition sy_jesys = new Condition("SY_JESYS", ConditionEnum.EQ.getType(), "1");
                        Condition conditionOr = new Condition("", ConditionEnum.OR.getType(), Lists.newArrayList(sy_jecore, sy_jecore_null));
                        condition.setValue(Lists.newArrayList(sy_jesys, conditionOr));
                    } else {
                        //" AND (SY_JECORE!='1' OR SY_JECORE IS NULL)";
                        query.addCustom("", ConditionEnum.AND, Lists.newArrayList(sy_jecore, sy_jecore_null));
                    }
                } else if (condition != null) {
                    // querySql = querySql.replace("SY_JESYS='1'", "1=1");
                    query.getCustom().remove(condition);
                }
            }

            ConditionsWrapper selectDic = query.buildWrapper();

            // 添加字典配置sql
            if (StringUtil.isNotEmpty(ddWhereSql)) {
                //formatSqlParameter 替换Sql中的系统变量 非预处理赋值
                selectDic.apply(QueryBuilder.formatSqlParameter(ddWhereSql));
            }


            //获取树形信息
            DynaBean table = BeanUtils.getInstance().getResourceTable(tableName);
            if (table == null) {
                return array;
            }
            //资源表树形字段配置
            JSONTreeNode template = BeanUtils.getInstance().buildJSONTreeNodeTemplate((List<DynaBean>) table.get(BeanUtils.KEY_TABLE_COLUMNS));
            //使用英文
            if ("JE_CORE_DICTIONARYITEM".equals(tableName) && en) {
                template.setText("DICTIONARYITEM_ITEMNAME_EN");
                template.setEnField("DICTIONARYITEM_ITEMNAME");
            }

            String idField = template.getId();
            String codeField = template.getCode();
            String textField = template.getText();
            String parentField = template.getParent();

            //父级数据条件
            if (StringUtil.isNotEmpty(parentId)) {
                selectDic.eq(parentField, parentId);
            } else if (StringUtil.isNotEmpty(parentCode)) {
                // 为了支持客户允许地区可以多选 yangzhi改于20191111
                String[] split = parentCode.split(",");
                String parentCodes = StringUtil.buildArrayToString(split);
                List<DynaBean> parents = metaService.select(tableName, selectDic.clone().apply(" AND " + codeField + " in(" + parentCodes + ")"));
                if (!parents.isEmpty()) {
                    ArrayList<String> ids = Lists.newArrayList();
                    for (DynaBean bean : parents) {
                        ids.add(bean.getStr(idField, ""));
                    }
                    //父节点条件
                    selectDic.in(parentField, ids);
//                        querySql += " AND " + parentField + " in(" + StringUtil.buildArrayToString(list) + ")";
                } else {
                    throw new PlatformException("数据错误，根据CODE【" + parentCode + "】未找到父项值!", PlatformExceptionEnum.JE_CORE_DIC_UNKOWNPARENT_ERROR);
                }
            } else {
                selectDic.eq(parentField, rootId);
            }

            //排序条件
            selectDic.apply(orderSql);

            //查询数据
            List<DynaBean> datas = metaService.select(tableName, selectDic);
            for (DynaBean data : datas) {
                JSONTreeNode node = new JSONTreeNode();
                if (StringUtil.isNotEmpty(idField)) {
                    node.setId(data.getStr(idField));
                }
                if (StringUtil.isNotEmpty(codeField)) {
                    node.setCode(data.getStr(codeField));
                }
                if (StringUtil.isNotEmpty(textField)) {
                    node.setText(data.getStr(textField));
                }
                if (StringUtil.isNotEmpty(parentField)) {
                    node.setParent(data.getStr(parentField));
                }
                node.setBean(data.getValues());
                array.add(node);
            }
        } else {
            throw new PlatformException("该字典类型不支持联动!", PlatformExceptionEnum.JE_CORE_DIC_UNKOWN_ERROR);
        }
        return array;
    }
}